package com.eas.biz.service.grade.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eas.biz.dao.grade.dataobject.GradeInfoDO;
import com.eas.biz.dao.grade.dataobject.GradeInfoQuery;
import com.eas.biz.dao.grade.dataobject.GradeSubjectInfoDO;
import com.eas.biz.dao.grade.interfaces.GradeInfoDao;
import com.eas.biz.dao.grade.interfaces.GradeSubjectInfoDao;
import com.eas.biz.service.grade.domain.GradeInfo;
import com.eas.biz.service.grade.domain.GradeLevel;
import com.eas.biz.service.grade.domain.GradeSubjectInfo;
import com.eas.biz.service.grade.interfaces.GradeService;

@Service("gradeService")
public class GradeServiceImpl implements GradeService {

    @Autowired
    private GradeInfoDao gradeInfoDao;

    @Autowired
    private GradeSubjectInfoDao gradeSubjectInfoDao;

    public GradeInfo getGradeInfo(long examId, boolean withSubjectInfo) {
        GradeInfoQuery query = new GradeInfoQuery();
        query.setExamId(examId);
        List<GradeInfoDO> list = gradeInfoDao.selectByQuery(query);
        if (list == null || list.size() == 0) {
            return null;
        }

        GradeInfo gradeInfo = buildGradeInfo(list.get(0));
        int rank = 1;
        for (GradeInfoDO level : list) {
            gradeInfo.addGradeLevel(buildGradeLevel(level, rank++));
        }

        if (withSubjectInfo) {
            Map<String, GradeSubjectInfo> subjectMap = getGradeSubjectInfoMap(examId);
            if (subjectMap != null && subjectMap.size() > 0) {
                for (GradeSubjectInfo subjectInfo : subjectMap.values()) {
                    gradeInfo.addSubjectInfo(subjectInfo);
                }
            }
        }

        return gradeInfo;
    }

    public Map<String, GradeSubjectInfo> getGradeSubjectInfoMap(long examId) {
        GradeInfoQuery query = new GradeInfoQuery();
        query.setExamId(examId);
        List<GradeSubjectInfoDO> list = gradeSubjectInfoDao.selectByQuery(query);
        if (list == null || list.size() == 0) {
            return new HashMap<String, GradeSubjectInfo>();
        }

        Map<String, GradeSubjectInfo> subjectMap = new HashMap<String, GradeSubjectInfo>();
        int rank = 1;
        for (GradeSubjectInfoDO subjectInfoDO : list) {
            GradeSubjectInfo subjectInfo = subjectMap.get(subjectInfoDO.getSubject());
            if (subjectInfo == null) {
                subjectInfo = buildGradeSubjectInfo(subjectInfoDO);
                subjectMap.put(subjectInfo.getSubject(), subjectInfo);
            }
            subjectInfo.addGradeLevel(buildGradeLevel(subjectInfoDO, rank++));
        }
        return subjectMap;
    }

    public GradeSubjectInfo getGradeSubjectInfo(long examId, String subject) {
        GradeInfoQuery query = new GradeInfoQuery();
        query.setExamId(examId);
        query.setSubject(subject);
        List<GradeSubjectInfoDO> list = gradeSubjectInfoDao.selectByQuery(query);
        if (list == null || list.size() == 0) {
            return null;
        }

        GradeSubjectInfo subjectInfo = buildGradeSubjectInfo(list.get(0));
        int rank = 1;
        for (GradeSubjectInfoDO level : list) {
            subjectInfo.addGradeLevel(buildGradeLevel(level, rank++));
        }
        return subjectInfo;
    }

    private GradeSubjectInfo buildGradeSubjectInfo(GradeSubjectInfoDO gradeSubjectInfoDO) {
        GradeSubjectInfo subject = new GradeSubjectInfo();
        subject.setId(gradeSubjectInfoDO.getId());
        subject.setExamId(gradeSubjectInfoDO.getExamId());
        subject.setSubject(gradeSubjectInfoDO.getSubject());
        return subject;
    }

    private GradeInfo buildGradeInfo(GradeInfoDO gradeInfoDO) {
        GradeInfo grade = new GradeInfo();
        grade.setId(gradeInfoDO.getId());
        grade.setExamId(gradeInfoDO.getExamId());
        return grade;
    }

    private GradeLevel buildGradeLevel(GradeInfoDO gradeInfoDO, int rank) {
        GradeLevel level = new GradeLevel();
        level.setLevel(gradeInfoDO.getLevel());
        level.setComment(gradeInfoDO.getComment());
        level.setScore(gradeInfoDO.getScore());
        level.setRank(rank);
        return level;
    }

}
